﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using MM.Common.IRemoteDataBase;
using System.ServiceModel;

namespace MM.Common.DBBase
{
    public class DbRemoteOracle : DbBase
    {
        // Fields
        private string dataSource;
        private string registerCode;
        private RemoteQuery remoteQuery;
        private RemoteTransaction remoteTransaction;

        // Methods
        protected override bool BeginTransaction()
        {
            base.ClearErrorMessage();
            try
            {
                if (!this.CheckTransaction())
                {
                    base.errorMessage.Append("事务服务不能使用!");
                    return false;
                }
                string error = "";
                if (!this.remoteTransaction.RemoteSetRegisterCode(ref error, this.registerCode))
                {
                    base.errorMessage.Append(error);
                    return false;
                }
                if (this.remoteTransaction.RemoteDBTransactionBegin(ref error))
                {
                    return true;
                }
                base.errorMessage.Append(error);
                return false;
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
                return false;
            }
        }

        private bool CheckQuery()
        {
            try
            {
                if (this.remoteQuery.State != CommunicationState.Opened)
                {
                    if (this.remoteQuery.State != CommunicationState.Created)
                    {
                        this.remoteQuery = new RemoteQuery();
                    }
                    this.remoteQuery.Open();
                }
                return (this.remoteQuery.State == CommunicationState.Opened);
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
                return false;
            }
        }

        private bool CheckTransaction()
        {
            try
            {
                if (this.remoteTransaction.State != CommunicationState.Opened)
                {
                    if (this.remoteTransaction.State != CommunicationState.Created)
                    {
                        this.remoteTransaction = new RemoteTransaction();
                    }
                    this.remoteTransaction.Open();
                }
                return (this.remoteTransaction.State == CommunicationState.Opened);
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
                return false;
            }
        }

        protected override bool CommitTransaction()
        {
            base.ClearErrorMessage();
            string error = "";
            if (this.remoteTransaction.RemoteDBTransactionCommit(ref error))
            {
                return true;
            }
            base.errorMessage.Append(error);
            return false;
        }

        public override string DataSource()
        {
            return this.dataSource;
        }

        public override void DBClose()
        {
            if (this.remoteTransaction.State == CommunicationState.Opened)
            {
                this.remoteTransaction.Close();
            }
            if (this.remoteQuery.State == CommunicationState.Opened)
            {
                this.remoteQuery.Close();
            }
        }

        public override bool ExecuteProcedure(string procedurename, DataParamCol parms, bool commit)
        {
            OraParm[] parm = this.GetParm(parms);
            bool flag = true;
            base.ClearErrorMessage();
            if (commit && !this.TransactionBegin())
            {
                return false;
            }
            try
            {
                string error = "";
                if (this.remoteTransaction.RemoteDBExecuteProcedure(ref error, procedurename, ref parm))
                {
                    if (commit && !base.TransactionCommit())
                    {
                        flag = false;
                    }
                    if (flag && (parms != null))
                    {
                        for (int i = 0; i < parm.Length; i++)
                        {
                            if ((parm[i].Direction == ParameterDirection.Output) || (parm[i].Direction == ParameterDirection.InputOutput))
                            {
                                parms[i].Value = parm[i].Value;
                            }
                        }
                    }
                    return flag;
                }
                if (commit)
                {
                    base.TransactionRollback();
                }
                flag = false;
                base.errorMessage.Append(error);
            }
            catch (Exception exception)
            {
                if (commit)
                {
                    base.TransactionRollback();
                }
                base.errorMessage.Append(exception.Message);
                flag = false;
            }
            return flag;
        }

        public override bool ExecuteScalar(string commandtext, DataParamCol parms, ref object obj, bool close_db)
        {
            int index;
            base.ClearErrorMessage();
            if (!this.CheckQuery())
            {
                base.errorMessage.Append("查询服务不能使用!");
                return false;
            }
            string error = "";
            OraParm[] parm = this.GetParm(parms);
            string str2 = "";
            bool flag = false;
            if (!this.remoteQuery.RemoteDBExecuteScalar(this.registerCode, ref error, commandtext, parm, ref str2))
            {
                obj = null;
                base.errorMessage.Append(error);
                goto Label_011F;
            }
            if (str2 == null)
            {
                obj = null;
            }
            else
            {
                index = str2.IndexOf('\t');
                string str3 = str2.Substring(0, index);
                if (str3 == null)
                {
                    goto Label_0111;
                }
                if (!(str3 == "Byte[]"))
                {
                    if (str3 == "DBNull")
                    {
                        obj = DBNull.Value;
                        goto Label_011D;
                    }
                    if (str3 == "Decimal")
                    {
                        obj = Convert.ToDecimal(str2.Substring(index + 1));
                        goto Label_011D;
                    }
                    if (str3 == "DateTime")
                    {
                        obj = Convert.ToDateTime(str2.Substring(index + 1));
                        goto Label_011D;
                    }
                    goto Label_0111;
                }
                obj = Convert.FromBase64String(str2.Substring(index + 1));
            }
            goto Label_011D;
        Label_0111:
            obj = str2.Substring(index + 1);
        Label_011D:
            flag = true;
        Label_011F:
            if (base.autoClose && close_db)
            {
                this.DBClose();
            }
            return flag;
        }

        public override int ExecuteSql(string commandtext, DataParamCol parms, int nrows, bool commit)
        {
            base.ClearErrorMessage();
            if (commit && !this.TransactionBegin())
            {
                return -1;
            }
            OraParm[] parm = this.GetParm(parms);
            try
            {
                string error = "";
                int num = this.remoteTransaction.RemoteDBExecuteSql(ref error, commandtext, parm, nrows);
                if (num < 0)
                {
                    if (commit)
                    {
                        base.TransactionRollback();
                    }
                    base.errorMessage.Append(error);
                }
                else if (commit && !base.TransactionCommit())
                {
                    num = -1;
                }
                return num;
            }
            catch (Exception exception)
            {
                if (commit)
                {
                    base.TransactionRollback();
                }
                base.errorMessage.Append(exception.Message);
                return -1;
            }
        }

        public override string GetDbDefault(string table_name, string column_name)
        {
            object obj2 = new object();
            string str = "";
            string commandtext = "SELECT F_GET_DB_DEFAULT(:tname ,:cname) FROM DUAL ";
            DataParamCol parms = new DataParamCol();
            parms.AddBatch(new object[] { "tname", table_name, "cname", column_name });
            if (base.ExecuteScalar(commandtext, parms, ref obj2))
            {
                str = obj2.ToString();
                if ((str.Length >= 2) && (str[0] == '\''))
                {
                    str = str.Substring(1, str.Length - 2);
                }
            }
            return str;
        }

        public override DateTime GetDBTime()
        {
            object obj2 = new object();
            base.ExecuteScalar("SELECT SYSDATE FROM DUAL", ref obj2);
            return (DateTime)obj2;
        }

        protected OraParm[] GetParm(DataParamCol parmcol)
        {
            if (parmcol == null)
            {
                return null;
            }
            OraParm[] parmArray = new OraParm[parmcol.Count];
            for (int i = 0; i < parmcol.Count; i++)
            {
                if (parmcol[i].Value == null)
                {
                    parmArray[i] = new OraParm(parmcol[i].Name, DBNull.Value, parmcol[i].Direction);
                }
                else
                {
                    parmArray[i] = new OraParm(parmcol[i].Name, parmcol[i].Value, parmcol[i].Direction);
                }
            }
            return parmArray;
        }

        protected OraParm[] GetParm(DataParamCol parmcol, ref string cursor_name)
        {
            if (parmcol == null)
            {
                return null;
            }
            int count = parmcol.Count;
            for (int i = 0; i < parmcol.Count; i++)
            {
                if ((parmcol[i].Type != null) && (parmcol[i].Type.ToString() == "System.Boolean"))
                {
                    count--;
                    cursor_name = parmcol[i].Name;
                    break;
                }
            }
            OraParm[] parmArray = new OraParm[count];
            int index = 0;
            for (int j = 0; j < parmcol.Count; j++)
            {
                if (cursor_name != parmcol[j].Name)
                {
                    parmArray[index] = new OraParm(parmcol[j].Name, parmcol[j].Value, parmcol[j].Direction);
                    index++;
                }
            }
            return parmArray;
        }

        protected override void GetSqlParmLen()
        {
            try
            {
                string commandtext = "SELECT DATA_LENGTH FROM USER_TAB_COLUMNS WHERE TABLE_NAME = :tname AND COLUMN_NAME = :cname";
                object obj2 = new object();
                DataParamCol parms = new DataParamCol();
                parms.Add("tname", "KTSYS_CHANGE_SQL");
                parms.Add("cname", "PARM");
                base.ExecuteScalar(commandtext, parms, ref obj2);
                if (obj2 != null)
                {
                    base.sqlParmLen = Convert.ToInt16(obj2);
                }
            }
            catch
            {
            }
        }

        protected bool Init()
        {
            try
            {
                this.remoteTransaction = new RemoteTransaction();
                this.remoteQuery = new RemoteQuery();
                return true;
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
                return false;
            }
        }

        protected override bool Open()
        {
            bool flag = false;
            base.ClearErrorMessage();
            try
            {
                if (!this.CheckTransaction())
                {
                    base.errorMessage.Append("事务服务不能使用!");
                    return false;
                }
                string error = "";
                if (!this.remoteTransaction.RemoteSetRegisterCode(ref error, this.registerCode))
                {
                    base.errorMessage.Append(error);
                    return flag;
                }
                flag = true;
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
            }
            return flag;
        }

        public override bool Open(string connectstring)
        {
            base.ClearErrorMessage();
            if (!this.Init())
            {
                return false;
            }
            string error = "";
            int index = connectstring.IndexOf(";Password=");
            this.dataSource = connectstring.Substring(0, index);
            connectstring = connectstring.Substring(index + 10);
            index = connectstring.IndexOf(";NODE=");
            string password = connectstring.Substring(0, index);
            string node = connectstring.Substring(index + 6);
            if (!this.remoteQuery.RemoteRegister(ref this.registerCode, ref error, node, password))
            {
                base.errorMessage.Append(error);
                return false;
            }
            if (!this.remoteTransaction.RemoteSetRegisterCode(ref error, this.registerCode))
            {
                base.errorMessage.Append(error);
                return false;
            }
            return true;
        }

        public override bool Retrieve(string commandtext, DataParamCol parms, ref DataTable dt, bool close_db)
        {
            bool flag = false;
            base.ClearErrorMessage();
            if (!this.CheckQuery())
            {
                base.errorMessage.Append("查询服务不能使用!");
            }
            else
            {
                try
                {
                    OraParm[] parm = this.GetParm(parms);
                    string error = "";
                    string str2 = this.remoteQuery.RemoteDBRetrieve(this.registerCode, ref error, commandtext, parm, dt.TableName);
                    if (str2 != string.Empty)
                    {
                        dt.ReadXml(new StringReader(str2.Trim()));
                        dt.AcceptChanges();
                        flag = true;
                    }
                    else
                    {
                        base.errorMessage.Append("接收到远程服务上的数据为空!\r\n" + error);
                    }
                }
                catch (Exception exception)
                {
                    base.errorMessage.Append(exception.Message);
                }
            }
            if (base.autoClose && close_db)
            {
                this.DBClose();
            }
            return flag;
        }

        public override bool Retrieve(string[] commandtexts, DataParamCol[] parms, ref DataTable[] dts, bool close_db)
        {
            bool flag = false;
            base.ClearErrorMessage();
            if (!this.CheckQuery())
            {
                base.errorMessage.Append("查询服务不能使用!");
            }
            else
            {
                try
                {
                    int length = commandtexts.Length;
                    OraParm[][] parmArray = new OraParm[length][];
                    string[] strArray = new string[length];
                    for (int i = 0; i < length; i++)
                    {
                        if ((parms.Length >= length) && (parms[i] != null))
                        {
                            parmArray[i] = this.GetParm(parms[i]);
                        }
                        else
                        {
                            parmArray[i] = new OraParm[0];
                        }
                        strArray[i] = dts[i].TableName;
                    }
                    string error = "";
                    string[] strArray2 = this.remoteQuery.RemoteDBRetrieveArray(this.registerCode, ref error, commandtexts, parmArray, strArray);
                    if (strArray2.Length > 0)
                    {
                        for (int j = 0; j < length; j++)
                        {
                            dts[j].ReadXml(new StringReader(strArray2[j].Trim()));
                            dts[j].AcceptChanges();
                        }
                        flag = true;
                    }
                    else
                    {
                        base.errorMessage.Append("接收到远程服务上的数据为空!\r\n" + error);
                    }
                }
                catch (Exception exception)
                {
                    base.errorMessage.Append(exception.Message);
                }
            }
            if (base.autoClose && close_db)
            {
                this.DBClose();
            }
            return flag;
        }

        public override bool RetrieveProcedure(string procedure_name, DataParamCol parms, ref DataTable dt, bool close_db)
        {
            bool flag = false;
            string str = "";
            OraParm[] parm = this.GetParm(parms, ref str);
            base.ClearErrorMessage();
            if (!this.CheckQuery())
            {
                base.errorMessage.Append("查询服务不能使用!");
            }
            try
            {
                string error = "";
                string str3 = this.remoteQuery.RemoteDBRetrieveProcedure(this.registerCode, ref error, procedure_name, ref parm, str, dt.TableName);
                if (str3 != string.Empty)
                {
                    dt.ReadXml(new StringReader(str3.Trim()));
                    dt.AcceptChanges();
                    if (parms != null)
                    {
                        for (int i = 0; i < parm.Length; i++)
                        {
                            if ((parm[i].Direction == ParameterDirection.Output) || (parm[i].Direction == ParameterDirection.InputOutput))
                            {
                                parms[i].Value = parm[i].Value;
                            }
                        }
                    }
                    flag = true;
                }
                else
                {
                    base.errorMessage.Append("接收到远程服务上的数据为空!\r\n" + error);
                }
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
            }
            if (base.autoClose && close_db)
            {
                this.DBClose();
            }
            return flag;
        }

        protected override bool RollbackTransaction()
        {
            try
            {
                string error = "";
                if (this.remoteTransaction.RemoteDBTransactionRollback(ref error))
                {
                    return true;
                }
                base.errorMessage.Append(error);
                return false;
            }
            catch (Exception exception)
            {
                base.errorMessage.Append(exception.Message);
                return false;
            }
        }

        public override int RunSql(string[] commandtexts, DataParamCol[] parms, int[] nrows, bool commit)
        {
            int num = 0;
            base.ClearErrorMessage();
            try
            {
                if (commit && !this.TransactionBegin())
                {
                    return -1;
                }
                for (int i = 0; i < commandtexts.Length; i++)
                {
                    num = i + 1;
                    int num3 = 0;
                    if (((parms != null) && (parms.Length >= (i + 1))) && (parms[i] != null))
                    {
                        num3 = this.ExecuteSql(commandtexts[i], parms[i], nrows[i], false);
                    }
                    else
                    {
                        num3 = this.ExecuteSql(commandtexts[i], new DataParamCol(), nrows[i], false);
                    }
                    if (num3 < 0)
                    {
                        throw new DataException(commandtexts[i] + "执行不成功!\r\n" + base.ErrorMessage);
                    }
                }
                if (commit && !base.TransactionCommit())
                {
                    return -1;
                }
                num = 0;
            }
            catch (Exception exception)
            {
                if (commit)
                {
                    base.TransactionRollback();
                }
                base.errorMessage.Append(exception.Message);
            }
            return num;
        }

        public override bool TransactionBegin()
        {
            return (base.TransactionBegin() && this.remoteTransaction.RemoteSetRecordParameter(base.tableOrder, base.sqlParmLen, base.transactionID));
        }

        // Properties
        public override bool IsExistTransaction
        {
            get
            {
                return this.remoteTransaction.RemoteDBIsExistTransaction();
            }
        }

        public override bool IsOpen
        {
            get
            {
                base.ClearErrorMessage();
                if (!this.CheckTransaction())
                {
                    base.errorMessage.Append("事务服务不能使用!");
                    return false;
                }
                if (!this.CheckQuery())
                {
                    base.errorMessage.Append("查询服务不能使用!");
                    return false;
                }
                return ((this.remoteTransaction.State == CommunicationState.Opened) && (this.remoteQuery.State == CommunicationState.Opened));
            }
        }
    }
}
